﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace TimeClockLib
{
    class TimeClockView : INotifyPropertyChanged 
    {
        private TimeClockLib.CommandViewModel _tagClockCommand;
        public TimeClockLib.CommandViewModel TagClockCommand
        {
            get
            {
                _tagClockCommand = _tagClockCommand ?? new CommandViewModel("tagClock",
                    new RelayCommand( i =>
                    {
                        this.SelectedUser.TagClock();
                    })
                );
                return _tagClockCommand;
            }            
        }

        private TimeClockLib.CommandViewModel _closeHistory;
        public TimeClockLib.CommandViewModel CloseHistory
        {
            get
            {
                _closeHistory = _closeHistory ?? new CommandViewModel("Close",
                    new RelayCommand(i =>
                    {
                        DisplayHistoryDalog = System.Windows.Visibility.Collapsed;
                    })
                );
                return _closeHistory;
            }            
        }

        private TimeClockLib.CommandViewModel _showHistory;
        public TimeClockLib.CommandViewModel ShowHistory
        {
            get
            {
                _showHistory = _showHistory ?? new CommandViewModel("History",
                    new RelayCommand(i =>
                    {
                        DisplayHistoryDalog = System.Windows.Visibility.Visible;
                    })
                );
                return _showHistory;
            }            
        }

        public TimeClockView() 
        {
            
            
            #region time diffs
            TimeSpan diff1 = TimeSpan.FromDays(1);
            TimeSpan diff2 = TimeSpan.FromDays(2);
            TimeSpan diff3 = TimeSpan.FromDays(3);
            TimeSpan diff4 = TimeSpan.FromDays(4);
            TimeSpan diff5 = TimeSpan.FromDays(7);
            TimeSpan diff6 = TimeSpan.FromDays(8);
            TimeSpan diff7 = TimeSpan.FromDays(9);
            TimeSpan diff8 = TimeSpan.FromDays(10);
            TimeSpan diff9 = TimeSpan.FromDays(11);
            TimeSpan diff10 = TimeSpan.FromDays(12);             
            #endregion
            this.Users = new ObservableCollection<UserView>();
            #region create users
            this.Users.Add
                (
                    new UserView
                    {
                        FirstName = "Montgomery",
                        LastName = "Burns",
                        IsClockedIn = false,
                        UserImage = "/TimeClockLib;component/burns.ico",
                        CurentPayPeroid = new ObservableCollection<WorkPeroid>() 
                    { 
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff10),
                            ClockOut = DateTime.Now.Subtract(diff10).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff9),
                            ClockOut = DateTime.Now.Subtract(diff9).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff8),
                            ClockOut = DateTime.Now.Subtract(diff8).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff7),
                            ClockOut = DateTime.Now.Subtract(diff7).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff6),
                            ClockOut = DateTime.Now.Subtract(diff6).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff5),
                            ClockOut = DateTime.Now.Subtract(diff5).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff4),
                            ClockOut = DateTime.Now.Subtract(diff4).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff3),
                            ClockOut = DateTime.Now.Subtract(diff3).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff2),
                            ClockOut = DateTime.Now.Subtract(diff2).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff1),
                            ClockOut = DateTime.Now.Subtract(diff1).AddHours(8)                            
                        }                      
                    }
                    }
                );
            this.Users.Add
            (
                new UserView
                {
                    FirstName = "Bart",
                    LastName = "Simpson",
                    IsClockedIn = true,
                    UserImage = "/TimeClockLib;component/bart.ico",
                    CurentPayPeroid = new ObservableCollection<WorkPeroid>() 
                    { 
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff10),
                            ClockOut = DateTime.Now.Subtract(diff10).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff9),
                            ClockOut = DateTime.Now.Subtract(diff9).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff8),
                            ClockOut = DateTime.Now.Subtract(diff8).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff7),
                            ClockOut = DateTime.Now.Subtract(diff7).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff6),
                            ClockOut = DateTime.Now.Subtract(diff6).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff5),
                            ClockOut = DateTime.Now.Subtract(diff5).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff4),
                            ClockOut = DateTime.Now.Subtract(diff4).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff3),
                            ClockOut = DateTime.Now.Subtract(diff3).AddHours(8)                            
                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff2),
                            ClockOut = DateTime.Now.Subtract(diff2).AddHours(8)                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now.Subtract(diff1),
                            ClockOut = DateTime.Now.Subtract(diff1).AddHours(8)  
                            
                        },
                        new WorkPeroid
                        {
                            ClockIn = DateTime.Now
                        }
                    }
                }
            ); 
            #endregion
            foreach (var usr in this.Users)
            {
                usr.PropertyChanged += new PropertyChangedEventHandler(usr_PropertyChanged);
                usr.AtachListners();
            }
            this.Users[0].IsSelected = true;
            Changed("Users");
        }

        void usr_PropertyChanged(object sender, PropertyChangedEventArgs e) 
        {
            if (e.PropertyName == "IsSelected")
            {
                var tUser = sender as UserView;
                this.SelectedUser = tUser;
            }
            if (e.PropertyName == "IsClockedIn")
            {
                Changed("TagTimeText");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void Changed(string propertyName) 
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public ObservableCollection<UserView> Users { get; set; }

        private TimeClockLib.UserView _selectedUser;
        public TimeClockLib.UserView SelectedUser 
        {
            get
            {
                return _selectedUser;
            }
            set
            {
                if (_selectedUser != value)
                {
                    _selectedUser = value;
                    Changed("SelectedUser");
                    Changed("TagTimeText");
                }
            }
        }

        public String testPassword { get; set; }
        
        private string _searchLabel = "Name";
        public string SearchLabel 
        {
            get
            {
                return _searchLabel;
            }
            set
            {
                if (_searchLabel != value)
                {
                    _searchLabel = value;
                    Changed("SearchLabel");
                }
            }
        }
        
        public string TagTimeText 
        {
            get
            {
                if (this.SelectedUser.IsClockedIn)
                {
                    return "Clock Out";
                }
                else
                {
                    return "Clock In";
                }
            }            
        }

        private System.Windows.Visibility _displayHistoryDalog = System.Windows.Visibility.Hidden;
        public System.Windows.Visibility DisplayHistoryDalog 
        {
            get
            {
                return _displayHistoryDalog;
            }
            set
            {
                if (_displayHistoryDalog != value)
                {
                    _displayHistoryDalog = value;
                    Changed("DisplayHistoryDalog");
                }
            }
        }

        
    }

    class UserView : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void Changed(string propertyName) 
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        
        public string FullName 
        {
            get
            {
                return string.Format("{0} {1}",this.FirstName,this.LastName);
            }
            
        }

        private string _firstName;
        public string FirstName 
        {
            get
            {
                return _firstName;
            }
            set
            {
                if (_firstName != value)
                {
                    _firstName = value;
                    Changed("FirstName");
                    Changed("FullName");
                }
            }
        }
        private string _lastName;
        public string LastName 
        {
            get
            {
                return _lastName;
            }
            set
            {
                if (_lastName != value)
                {
                    _lastName = value;
                    Changed("LastName");
                    Changed("FullName");
                }
            }
        }
        private string _userImage;
        public string UserImage
        {
            get
            {
                return _userImage;
            }
            set
            {
                if (_userImage != value)
                {
                    _userImage = value;
                    Changed("UserImage");
                }
            }
        }

        public string ClockedInImage
        {
            get
            {
                var sIcon = this.IsClockedIn ? "bullet_ball_green.png" : "bullet_ball_red.png";
                return string.Format("/TimeClockLib;component/{0}", sIcon);
            }
        }

        
        public string ClockedInStatus
        {
            get
            {
                if (this.IsClockedIn)
                {
                    return string.Format("Clocked in at {0}", this.LastWorkPeroid.ClockIn);
                }
                return string.Format("Clocked out at {0}", this.LastWorkPeroid.ClockOut);
                
            }
            
        }

        private bool _isClockedIn;
        public bool IsClockedIn
        {
            get
            {
                return _isClockedIn;
            }
            set
            {
                if (_isClockedIn != value)
                {
                    _isClockedIn = value;
                    Changed("IsClockedIn");
                    Changed("ClockedInStatus");
                    Changed("ClockedInImage");
                }
            }
        }
        private TimeClockLib.WorkPeroid _lastWorkPeroid;
        public TimeClockLib.WorkPeroid LastWorkPeroid
        {
            get
            {
                if (this._lastWorkPeroid == null)
                {
                    this._lastWorkPeroid = this.CurentPayPeroid.OrderBy(c => c.ClockIn).Last();
                }
                return _lastWorkPeroid;
            }
            set
            {
                if (_lastWorkPeroid != value)
                {
                    _lastWorkPeroid = value;
                    Changed("LastWorkPeroid");
                }
            }
        }

        public ObservableCollection<WorkPeroid> CurentPayPeroid { get; set; }

        private bool _isSelected;
        public bool IsSelected
        {
            get
            {
                return _isSelected;
            }
            set
            {
                if (_isSelected != value)
                {
                    _isSelected = value;
                    Changed("IsSelected");
                }
            }
        }

        internal void AtachListners()
        {
            foreach (var tim in this.CurentPayPeroid)
            {
                tim.PropertyChanged += new PropertyChangedEventHandler(tim_PropertyChanged);
            }
        }

        void tim_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            
        }

        internal void TagClock()
        {
            if (this.LastWorkPeroid.ClockOut != DateTime.MinValue)
            {
                var twp = new WorkPeroid();
                this.CurentPayPeroid.Add(twp);
                this.LastWorkPeroid = twp;
                this.LastWorkPeroid.ClockIn = DateTime.Now;
                this.IsClockedIn = true;
            }
            else
            {
                this.LastWorkPeroid.ClockOut = DateTime.Now;
                this.IsClockedIn = false;
            }
        }
    }

    class WorkPeroid : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void Changed(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        private System.DateTime _clockIn;
        public System.DateTime ClockIn
        {
            get
            {
                return _clockIn;
            }
            set
            {
                if (_clockIn != value)
                {
                    _clockIn = value;
                    Changed("ClockIn");
                }
            }
        }
        private System.DateTime _clockOut;
        public System.DateTime ClockOut
        {
            get
            {
                return _clockOut;
            }
            set
            {
                if (_clockOut != value)
                {
                    _clockOut = value;
                    Changed("ClockOut");
                }
            }
        }
        private bool _hadManualEdit;
        public bool HadManualEdit
        {
            get
            {
                return _hadManualEdit;
            }
            set
            {
                if (_hadManualEdit != value)
                {
                    _hadManualEdit = value;
                    Changed("HadManualEdit");
                }
            }
        }

        public String ManualEditStr { get; set; }

        private bool _isSelected;
        public bool IsSelected
        {
            get
            {
                return _isSelected;
            }
            set
            {
                if (_isSelected != value)
                {
                    _isSelected = value;
                    Changed("IsSelected");
                }
            }
        }
    }
}
